package com.liuh.fram.io;

import java.io.ByteArrayOutputStream;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

import com.liuh.fram.err.LocalException;
import com.liuh.fram.err.LocalException.ErrorType;

/**
 * @note zip 解压缩
 * @author liuh
 * */
public class ZLibTools extends CompressTools {

	public static final int BUFFER = 1024;

	@Override
	public byte[] compress(byte[] value) throws Exception {
		return compress(value, 0, value.length, Deflater.BEST_COMPRESSION);
	}

	@Override
	public byte[] decompress(byte[] value) throws Exception {
		if(value.length<1){
			throw new LocalException(ErrorType.parseErr);
		}
		byte[] output = new byte[0];
		ByteArrayOutputStream bos = new ByteArrayOutputStream(value.length);
		Inflater decompressor = new Inflater();
		try {
			decompressor.reset();
			decompressor.setInput(value);
			final byte[] buf = new byte[BUFFER];
			while (!decompressor.finished()) {
				int count = decompressor.inflate(buf);
				bos.write(buf, 0, count);
			}
			output = bos.toByteArray();
		}catch (Exception e) {
			throw new LocalException(ErrorType.parseErr);
		} finally {
			bos.close();
			decompressor.end();
		}
		return output;
	}

	/**
	 * @note 压缩
	 * @author liuh
	 * @throws AppException
	 * */
	public byte[] compress(byte[] value, int offset, int length,
			int compressionLevel) throws Exception {
		byte[] output = new byte[0];
		ByteArrayOutputStream bos = new ByteArrayOutputStream(length);
		Deflater compressor = new Deflater();
		try {
			compressor.reset();
			compressor.setLevel(compressionLevel); // 将当前压缩级别设置为指定值。
			compressor.setInput(value, offset, length);
			compressor.finish(); // 调用时，指示压缩应当以输入缓冲区的当前内容结尾。
			// Compress the data
			final byte[] buf = new byte[BUFFER];
			while (!compressor.finished()) {
				// 如果已到达压缩数据输出流的结尾，则返回 true。
				int count = compressor.deflate(buf);
				// 使用压缩数据填充指定缓冲区。
				bos.write(buf, 0, count);
			}
			output = bos.toByteArray();
		}catch (Exception e) {
			throw new LocalException(ErrorType.parseErr);
		} finally {
			bos.close();
			compressor.end(); // 关闭解压缩器并放弃所有未处理的输入。
		}
		return output;
	}

	public byte[] compress(byte[] value, int offset, int length)
			throws Exception {
		// 最佳压缩的压缩级别
		return compress(value, offset, length, Deflater.BEST_COMPRESSION);
	}
}